#include "modbushost.h"
#include <QDebug>

ModbusHost::ModbusHost(QObject *parent) : QObject(parent)
{
    modbusDevice = nullptr;



}

void ModbusHost::modbus_disconnect()
{
    modbus_com = QString("");
    modbus_baudRate = QString("");
    modbus_addr = QString("");
    delete  modbusDevice;
    modbusDevice = nullptr;
}

/**
 *   @brief 连接设备
 *
 */
void ModbusHost::modbus_connect_slave(QVariantMap port_info)
{
    ret_code_t code;
    // 如果已经连接了，就断开连接
    if (modbusDevice && modbusDevice->state() == QModbusDevice::ConnectedState) {
           // 断开连接
        modbus_disconnect();
        code  = RET_DISCONNECT;
    }
    else {
        // 否则，建立连接
        if (!modbusDevice) {
            // 如果modbusDevice为空，创建一个新的设备
            modbusDevice = new QModbusRtuSerialMaster(this);
        }
        modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, port_info["com"].toString());
        modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, 0);
        modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, port_info["baudRate"].toString());
        modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, 8);
        modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, 1);
        qDebug()<<port_info["com"].toString()<<"--"<<port_info["baudRate"].toString();
        // 尝试连接设备
        if (modbusDevice->connectDevice()) {

            modbus_com = port_info["com"].toString();
            modbus_baudRate = port_info["baudRate"].toString();
            modbus_addr = port_info["addr"].toString();
            qDebug() << "连接成功";
            code = RET_CONNECT_SUCCESS;
        } else {
            //ui->open_serial_btn->setText("建立连接");
            qDebug() << "连接失败";
            modbus_disconnect();
            code = RET_CONNECT_ERR;
        }
    }
    emit modbus_ret_code(code);
}
/**
    @brief 异步处理
*/
void ModbusHost::modbus_task_SearchPort()
{
    QStringList portList;
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        portList << info.portName(); // 仅添加串口名称，不执行 open/close 操作
    }
    emit modbus_task_sendSearchPort(portList); // 发出信号，通知主线程
    qDebug() << "task_SearchPort";
}

void ModbusHost::modbus_task_get_cfg()
{
    QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters, MODBUS_HOLD_REG_START_ADDR, MODBUS_HOLD_REG_SIZE);
    // 发送读请求
    if (auto *reply = modbusDevice->sendReadRequest(readUnit, modbus_addr.toInt()))
    {
        if (!reply->isFinished())
        {
            connect(reply, &QModbusReply::finished, this, &ModbusHost::read_hold_Reply);
        }
        else
        {
            // 如果发送失败，则立即删除 reply
            delete reply;
        }
    }
    else
    {
        qDebug() << "发送读请求失败：" << modbusDevice->errorString();
    }
    qDebug() << "task_get_cfg";
}

void ModbusHost::modbus_task_get_env()
{
    QModbusDataUnit readUnit(QModbusDataUnit::InputRegisters, MODBUS_INPUT_REG_START_ADDR, MODBUS_INPUT_REG_SIZE);
    // 发送读请求
    if (auto *reply = modbusDevice->sendReadRequest(readUnit, modbus_addr.toInt()))
    {
        if (!reply->isFinished())
        {
            connect(reply, &QModbusReply::finished, this, &ModbusHost::read_input_Reply);
        }
        else
        {
            // 如果发送失败，则立即删除 reply
            delete reply;
        }
    }
    else
    {
        qDebug() << "发送读请求失败：" << modbusDevice->errorString();
    }
    qDebug() << "task_get_env";
}

void ModbusHost::read_hold_Reply()
{
    auto reply = qobject_cast<QModbusReply *>(sender());
    if (!reply)
        return;
    QVector<QString> recv_list(MODBUS_HOLD_REG_SIZE,"-");
    if (reply->error() == QModbusDevice::NoError)
    {
        // 处理成功的 Modbus 数据
        const QModbusDataUnit unit = reply->result();

        for(int i=0;i<MODBUS_HOLD_REG_SIZE;i++)

           recv_list[i] = QString::number(unit.value(i)>32767 ? unit.value(i) - 65536 : unit.value(i));
    }
    else
    {

        qDebug() << "Modbus 错误：" << reply->errorString();
    }
    emit modbus_get_cfg_finish(recv_list);
    reply->deleteLater(); // 删除 reply 避免内存泄漏
}
void ModbusHost::read_input_Reply()
{
    auto reply = qobject_cast<QModbusReply *>(sender());
    if (!reply)
        return;
    QVector<QString> recv_list(MODBUS_INPUT_REG_SIZE,"-");
    if (reply->error() == QModbusDevice::NoError)
    {
        // 处理成功的 Modbus 数据
        const QModbusDataUnit unit = reply->result();

        for(int i=0;i<MODBUS_INPUT_REG_SIZE;i++)
        {
            qDebug()<<"i="<<unit.value(i) ;
             recv_list[i] = QString::number(unit.value(i)>32767 ? unit.value(i) - 65536 : unit.value(i));

        }


    }
    else
    {

        qDebug() << "Modbus 错误：" << reply->errorString();
    }
    emit modbus_get_env_finish(recv_list);
    reply->deleteLater(); // 删除 reply 避免内存泄漏
}


void ModbusHost::modbus_write_hold(qint16 regaddr,qint16 data)
{
    // 设置 Modbus 地址和请求类型

    QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, regaddr, 1); // 写寄存器地址 0，写 1 个寄存器
    writeUnit.setValue(0, data);

    // 发送写请求
    if (auto *reply = modbusDevice->sendWriteRequest(writeUnit,modbus_addr.toInt()))
    {
        if (!reply->isFinished())
        {

            connect(reply, &QModbusReply::finished, this, &ModbusHost::hold_write_reply);
        }
        else
        {
            delete reply;
        }
    }
    else
    {

    }
}
void ModbusHost::hold_write_reply()
{
    auto reply = qobject_cast<QModbusReply *>(sender());
    ret_code_t ret;
    if (!reply)
        return;

    if (reply->error() == QModbusDevice::NoError)
    {
        // 处理成功的 Modbus 数据
        const QModbusDataUnit unit = reply->result();

        ret = RET_WRITE_SUCCESS;


    }
    else
    {
        ret = RET_WRITE_ERR;

    }
    emit modbus_ret_code(ret);
    reply->deleteLater(); // 删除 reply 避免内存泄漏
}
